#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
图片爬取和处理工具类
用于从网络爬取真实图片并上传到MinIO
"""

import os
import requests
from io import BytesIO
from PIL import Image
from backend.tools.minio_client import minio_client
import cairosvg
import uuid
import time


class ImageCrawler:
    """图片爬取和处理工具类"""
    
    def __init__(self):
        """初始化图片爬虫"""
        # 这里可以配置真实的图片API密钥
        self.unsplash_access_key = "your_unsplash_access_key"
        self.pexels_api_key = "your_pexels_api_key"
    
    def generate_icon_svg(self, name, text, color="#888"):
        """
        生成图标SVG
        :param name: 图标名称
        :param text: 显示文本
        :param color: 图标颜色
        :return: SVG内容
        """
        svg_content = f'''<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
            <circle cx="50" cy="40" r="25" fill="{color}"/>
            <rect x="30" y="70" width="40" height="20" fill="{color}" rx="5"/>
            <text x="50" y="95" font-family="Arial" font-size="12" fill="#666" text-anchor="middle">{text}</text>
        </svg>'''
        return svg_content
    
    def generate_avatar_svg(self, name, text, color="#ccc"):
        """
        生成头像SVG
        :param name: 头像名称
        :param text: 显示文本
        :param color: 头像颜色
        :return: SVG内容
        """
        svg_content = f'''<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
            <circle cx="100" cy="70" r="40" fill="{color}"/>
            <rect x="60" y="120" width="80" height="60" fill="{color}" rx="10"/>
            <text x="100" y="190" font-family="Arial" font-size="16" fill="#999" text-anchor="middle">{text}</text>
        </svg>'''
        return svg_content
    
    def generate_service_svg(self, name, text, color="#3cc51f"):
        """
        生成服务图片SVG
        :param name: 服务名称
        :param text: 显示文本
        :param color: 服务图片颜色
        :return: SVG内容
        """
        svg_content = f'''<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
            <rect x="20" y="20" width="160" height="160" fill="{color}" rx="10"/>
            <circle cx="100" cy="100" r="30" fill="white" opacity="0.5"/>
            <text x="100" y="180" font-family="Arial" font-size="16" fill="white" text-anchor="middle">{text}</text>
        </svg>'''
        return svg_content
    
    def generate_banner_svg(self, name, text, color="#4a90e2"):
        """
        生成轮播图SVG
        :param name: 轮播图名称
        :param text: 显示文本
        :param color: 轮播图颜色
        :return: SVG内容
        """
        svg_content = f'''<svg width="600" height="300" xmlns="http://www.w3.org/2000/svg">
            <rect width="100%" height="100%" fill="{color}"/>
            <text x="50%" y="50%" font-family="Arial" font-size="32" fill="white" text-anchor="middle" dominant-baseline="middle">{text}</text>
        </svg>'''
        return svg_content
    
    def crawl_image_from_url(self, url, timeout=10):
        """
        从URL爬取图片
        :param url: 图片URL
        :param timeout: 超时时间
        :return: 图片二进制数据
        """
        try:
            headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
            }
            response = requests.get(url, headers=headers, timeout=timeout)
            response.raise_for_status()
            return response.content
        except Exception as e:
            print(f"爬取图片失败 {url}: {e}")
            return None
    
    def search_image_from_unsplash(self, query, count=1):
        """
        从Unsplash搜索图片
        :param query: 搜索关键词
        :param count: 返回图片数量
        :return: 图片URL列表
        """
        if not self.unsplash_access_key or self.unsplash_access_key == "your_unsplash_access_key":
            print("未配置Unsplash API密钥")
            return []
        
        try:
            url = "https://api.unsplash.com/search/photos"
            params = {
                "query": query,
                "per_page": count,
                "orientation": "landscape" if "banner" in query else "squarish"
            }
            headers = {
                "Authorization": f"Client-ID {self.unsplash_access_key}"
            }
            
            response = requests.get(url, params=params, headers=headers)
            response.raise_for_status()
            
            data = response.json()
            urls = []
            for photo in data.get("results", []):
                # 获取合适的图片尺寸
                if "banner" in query:
                    urls.append(photo["urls"]["regular"])  # 适用于轮播图
                else:
                    urls.append(photo["urls"]["small"])  # 适用于头像和服务图片
            
            return urls
        except Exception as e:
            print(f"从Unsplash搜索图片失败: {e}")
            return []
    
    def search_image_from_pexels(self, query, count=1):
        """
        从Pexels搜索图片
        :param query: 搜索关键词
        :param count: 返回图片数量
        :return: 图片URL列表
        """
        if not self.pexels_api_key or self.pexels_api_key == "your_pexels_api_key":
            print("未配置Pexels API密钥")
            return []
        
        try:
            url = "https://api.pexels.com/v1/search"
            params = {
                "query": query,
                "per_page": count
            }
            headers = {
                "Authorization": self.pexels_api_key
            }
            
            response = requests.get(url, params=params, headers=headers)
            response.raise_for_status()
            
            data = response.json()
            urls = []
            for photo in data.get("photos", []):
                # 获取合适的图片尺寸
                if "banner" in query:
                    urls.append(photo["src"]["large"])  # 适用于轮播图
                else:
                    urls.append(photo["src"]["medium"])  # 适用于头像和服务图片
            
            return urls
        except Exception as e:
            print(f"从Pexels搜索图片失败: {e}")
            return []
    
    def search_and_download_image(self, keyword, max_size=5*1024*1024):
        """
        搜索并下载图片
        :param keyword: 搜索关键词
        :param max_size: 最大图片大小
        :return: 图片二进制数据
        """
        # 首先尝试从Unsplash搜索
        urls = self.search_image_from_unsplash(keyword, 1)
        if not urls:
            # 如果Unsplash没有结果，尝试从Pexels搜索
            urls = self.search_image_from_pexels(keyword, 1)
        
        # 如果还是没有结果，返回None
        if not urls:
            print(f"未找到相关图片: {keyword}")
            return None
            
        # 尝试下载第一张可用图片
        for url in urls:
            image_data = self.crawl_image_from_url(url)
            if image_data and len(image_data) <= max_size:
                return image_data
                
        return None
    
    def svg_to_png(self, svg_content):
        """
        将SVG转换为PNG
        :param svg_content: SVG内容
        :return: PNG二进制数据
        """
        try:
            png_data = cairosvg.svg2png(bytestring=svg_content.encode('utf-8'))
            return png_data
        except Exception as e:
            print(f"SVG转换PNG失败: {e}")
            return None
    
    def resize_image(self, image_data, max_width=600, max_height=600):
        """
        调整图片大小
        :param image_data: 图片二进制数据
        :param max_width: 最大宽度
        :param max_height: 最大高度
        :return: 调整后的图片二进制数据
        """
        try:
            image = Image.open(BytesIO(image_data))
            
            # 如果图片尺寸超过限制，则调整大小
            if image.width > max_width or image.height > max_height:
                image.thumbnail((max_width, max_height), Image.Resampling.LANCZOS)
            
            # 转换为RGB模式（如果需要）
            if image.mode in ('RGBA', 'LA', 'P'):
                # 创建白色背景
                background = Image.new('RGB', image.size, (255, 255, 255))
                if image.mode == 'P':
                    image = image.convert('RGBA')
                background.paste(image, mask=image.split()[-1] if image.mode in ('RGBA', 'LA') else None)
                image = background
            
            # 保存为JPEG格式
            output = BytesIO()
            image.save(output, format='JPEG', quality=85)
            return output.getvalue()
        except Exception as e:
            print(f"调整图片大小失败: {e}")
            return image_data  # 返回原始数据
    
    def upload_image(self, image_data, folder, filename=None):
        """
        上传图片到MinIO
        :param image_data: 图片二进制数据
        :param folder: 存储文件夹
        :param filename: 文件名
        :return: 图片URL
        """
        try:
            if not filename:
                filename = f"{uuid.uuid4().hex}.jpg"
            
            object_name = f"{folder}/{filename}"
            minio_client.upload_bytes(object_name, image_data, content_type="image/jpeg")
            url = minio_client.presigned_get_url(object_name)
            return url
        except Exception as e:
            print(f"上传图片到MinIO失败: {e}")
            return None
    
    def process_icon(self, name, text, color="#888"):
        """
        处理图标（生成SVG并转换为PNG上传）
        :param name: 图标名称
        :param text: 显示文本
        :param color: 图标颜色
        :return: 图片URL
        """
        # 生成SVG
        svg_content = self.generate_icon_svg(name, text, color)
        
        # 转换为PNG
        png_data = self.svg_to_png(svg_content)
        if not png_data:
            return None
        
        # 上传到MinIO
        url = self.upload_image(png_data, "icons", f"{name}.png")
        return url
    
    def process_avatar(self, name, text, color="#ccc"):
        """
        处理头像（生成SVG并转换为PNG上传）
        :param name: 头像名称
        :param text: 显示文本
        :param color: 头像颜色
        :return: 图片URL
        """
        # 生成SVG
        svg_content = self.generate_avatar_svg(name, text, color)
        
        # 转换为PNG
        png_data = self.svg_to_png(svg_content)
        if not png_data:
            return None
        
        # 上传到MinIO
        url = self.upload_image(png_data, "avatars", f"{name}.png")
        return url
    
    def process_service_image(self, name, text, color="#3cc51f"):
        """
        处理服务图片（生成SVG并转换为PNG上传）
        :param name: 服务名称
        :param text: 显示文本
        :param color: 服务图片颜色
        :return: 图片URL
        """
        # 生成SVG
        svg_content = self.generate_service_svg(name, text, color)
        
        # 转换为PNG
        png_data = self.svg_to_png(svg_content)
        if not png_data:
            return None
        
        # 上传到MinIO
        url = self.upload_image(png_data, "services", f"{name}.png")
        return url
    
    def process_banner(self, name, text, color="#4a90e2"):
        """
        处理轮播图（生成SVG并转换为PNG上传）
        :param name: 轮播图名称
        :param text: 显示文本
        :param color: 轮播图颜色
        :return: 图片URL
        """
        # 生成SVG
        svg_content = self.generate_banner_svg(name, text, color)
        
        # 转换为PNG
        png_data = self.svg_to_png(svg_content)
        if not png_data:
            return None
        
        # 上传到MinIO
        url = self.upload_image(png_data, "banners", f"{name}.png")
        return url


# 创建全局实例
image_crawler = ImageCrawler()